/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package graphviewer;

import service.Service;
import java.util.*;

/**
 *
 * @author Sabitov Artem
 * @since 21.09.2013
 */
public class Parser {
	private HashMap<String, ArrayList<Node>> graphs;
	private ArrayList<Node> graph;
	private ArrayList<Node> nodes;
	private boolean[] mark;
	
	private String input;
	public static int nodeCount;
	public static int graphCount;
	
	public Parser() {
		graphs = new HashMap<>();
		graph = new ArrayList<>();
		nodes = new ArrayList<>();
		
//		input = "[[0,1,1,0,0,1,0],[1,0,1,0,0,0,0],[1,1,0,1,0,0,0],[0,0,1,0,0,0,0],[1,0,0,0,0,1,0],[0,0,0,0,1,0,0],[0,0,0,0,0,0,0]";

//		input = "[[0,1,1,0,1,0],[1,0,0,1,1,0],[1,0,0,0,1,1],[0,1,0,0,0,0],[1,1,1,0,0,1],[0,0,1,0,1,0]]";
//		input =  "[[0,1,1,0,1,0,0,0,1,0],"
//				+ "[1,0,1,0,0,0,0,0,0,0],"
//				+ "[1,0,0,0,0,0,0,0,0,0],"
//				+ "[0,1,0,0,1,0,0,0,0,0],"
//				+ "[1,0,0,1,0,0,0,0,0,1],"
//				+ "[0,0,0,0,0,0,0,0,0,0],"
//				+ "[0,0,0,0,0,0,0,1,0,0],"
//				+ "[0,0,0,0,0,0,1,0,0,0],"
//				+ "[1,0,0,0,0,0,0,0,0,0],"
//				+ "[0,1,0,1,0,0,0,0,0,0]" + "]";
		input = "[[1, 1, 0, 0, 0, 1, 1, 0],\n" +
				"[0, 1, 0, 0, 0, 0, 1, 1],\n" +
				"[1, 0, 1, 1, 0, 1, 1, 1],\n" +
				"[1, 1, 0, 0, 0, 1, 1, 0],\n" +
				"[0, 0, 0, 1, 1, 1, 1, 1],\n" +
				"[0, 1, 0, 0, 1, 1, 0, 1],\n" +
				"[1, 0, 1, 1, 0, 0, 1, 0],\n" +
				"[0, 0, 1, 0, 1, 0, 1, 1]]";
//		input = "[[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1]]";
	
		
		parseMatrix(input);
	}
	
	private void parseMatrix(String input) {
		for(int i = 0; i < input.length(); i++) {
			if(input.charAt(i) == '1' || input.charAt(i) == '0' ) {
				nodeCount++;
			}
		}
		nodeCount = (int) Math.sqrt(nodeCount);
		
		// добавляем ноды
		Random rnd = new Random();
		int[][] matrix = new int[nodeCount][nodeCount];
		for(int i = 0; i < nodeCount; i++) {
			Node node = new Node(rnd.nextInt(1000), rnd.nextInt(712));
			nodes.add(node);
		}
		
		// парсим смежную матрицу и приводим к int
		log("adjacent matrix:");
		String line = "| ";
		for(int i = 0, j = 0, k = 0; k < input.length(); k++) {
			if(input.charAt(k) == '1' || input.charAt(k) == '0' ) {
				matrix[i][j] = Integer.valueOf(String.valueOf(input.charAt(k)));
				line = line + String.valueOf(matrix[i][j]) + "  ";
				j++;
				if(j == nodeCount) {
					j = 0;
					i++;
					log(line + "|");
					line = "| ";
				}
			}
		}
		// добавляем ребра
		for(int i = 0; i < nodeCount; i++) {
			for(int j = 0; j < nodeCount; j++) {
				if(matrix[i][j] == 1) {
					nodes.get(i).setEdge(nodes.get(j));
				}
			}
		}
		
		// разбиваем ноды по группам на принадлежность графам
		mark = new boolean[nodeCount];
		for(int i = 0; i < nodeCount; i++) {
			graph = new ArrayList<>();
			Node node = nodes.get(i);
			if(!mark[i]) {
				mark[i] = true;
				graph.add(node);
			}
			graphTraversal(node, graph);
			if(!graph.isEmpty()) {
				graphs.put("ID_" + graphCount, (ArrayList<Node>)graph.clone());
				graphCount++;
			}
		}
		log("press \"Space\" to run calculation..");
	}
	
	private void graphTraversal(Node n, ArrayList<Node> array) {
		for(int i = n.getID(); i < nodeCount; i++) {
			Node node = nodes.get(i);
			if(n.checkEdge(node)) {
				if(!mark[i]) {
					array.add(node);
					mark[i] = true;
					graphTraversal(node, graph);
				}
			}
		}
	}
	
	public HashMap<String, ArrayList<Node>> getGraphs() {
		return (HashMap<String, ArrayList<Node>>) graphs.clone();
	}
	
	private void log(Object obj) {
		if(Service.getServiceState()) {
			Service.log(obj);
		}
	}
}
